package com.laxcen.intelligenttoy.BLE;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;

import com.apkfuns.logutils.LogUtils;

import org.reactivestreams.Subscription;

import java.util.List;

import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Action;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;

/**
 * 蓝牙工具类
 */
public class BLEUtils {
    private AppCompatActivity context;
    private BluetoothManager mBluetoothManager;//蓝牙管理者
    private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
    private BluetoothLeScanner mScanner;//蓝牙搜索器
    private Flowable scanFlowable;//扫描器被观察者
    private Disposable scanDisposable;//扫描器解除订阅工具
    private Consumer<BluetoothDevice> scanOnNext;

    public BLEUtils(AppCompatActivity context,Consumer<BluetoothDevice> scanOnNext) {
        this.context = context;
        this.scanOnNext = scanOnNext;
    }

    /**
     * 检查当前设备是否支持BLE
     */
    public BLEUtils checkBLE() {
        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Toast.makeText(context, "您的设备不支持蓝牙BLE，将关闭", Toast.LENGTH_SHORT).show();
            context.finish();
        }
        return this;
    }

    /**
     * 初始化BLE
     *
     * @return
     */
    public BLEUtils initBLE() {
        mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = mBluetoothManager.getAdapter();
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
            //方式一：请求打开蓝牙
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            context.startActivityForResult(intent, 1);
            //方式二：半静默打开蓝牙
            //低版本android会静默打开蓝牙，高版本android会请求打开蓝牙
//            mBluetoothAdapter.enable();
        }
        return this;
    }

    /**
     * 开始扫描操作
     *
     * @param deviceName 设备名称
     * @param macAddress 设备Mac地址
     */
    public BLEUtils startScan(final String deviceName, final String macAddress) {
        scanFlowable = Flowable.create(new FlowableOnSubscribe<BluetoothDevice>() {
            @Override
            public void subscribe(FlowableEmitter<BluetoothDevice> emitter) throws Exception {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                    //  >= android5.0搜索操作
                    mScanner = mBluetoothAdapter.getBluetoothLeScanner();
                    mScanner.startScan(new ScanCallback() {
                        /**
                         * 搜索到一个蓝牙设备时返回
                         * @param callbackType
                         * @param result
                         */
                        @Override
                        public void onScanResult(int callbackType, ScanResult result) {
                            super.onScanResult(callbackType, result);
                            BluetoothDevice device = result.getDevice();
                            if(device != null && device.getName() != null){
                                if (device.getName().equals(deviceName)
                                        && device.getAddress().equals(macAddress)
                                ) {
                                    //寻找到匹配设备，返回结果
                                    LogUtils.d(device);
                                    emitter.onNext(device);
                                    stopScan();
                                }
                            }
                        }

                        //批量返回扫描结果
                        //@param results 以前扫描到的扫描结果列表。
                        @Override
                        public void onBatchScanResults(List<ScanResult> results) {
                            super.onBatchScanResults(results);
                        }

                        //当扫描不能开启时回调
                        @Override
                        public void onScanFailed(int errorCode) {
                            super.onScanFailed(errorCode);
                        }
                    });
                } else {
                    mBluetoothAdapter.startLeScan(new BluetoothAdapter.LeScanCallback() {
                        @Override
                        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
                            if(device != null && device.getName() != null){
                                if (device.getName().equals(deviceName)
                                        && device.getAddress().equals(macAddress)
                                ) {
                                    //寻找到匹配设备，返回结果
                                    emitter.onNext(device);
                                    stopScan();
                                }
                            }
                        }
                    });
                }
            }
        }, BackpressureStrategy.ERROR)
                .subscribeOn(Schedulers.io()) //订阅工作线程 io线程
                .observeOn(AndroidSchedulers.mainThread());//观察者处理线程
        if (scanFlowable != null) {
            //订阅者建立关系
            scanDisposable = scanFlowable.subscribe(scanOnNext, new Consumer<Throwable>() {
                @Override
                public void accept(Throwable throwable) throws Exception {
                    OpenBleProgreessDialog.dismiss();
                }
            }, new Action() {
                @Override
                public void run() throws Exception {
                    OpenBleProgreessDialog.dismiss();
                }
            }, new Consumer<Subscription>() {
                @Override
                public void accept(Subscription subscription) throws Exception {
                    OpenBleProgreessDialog.show(context, "正在搜索设备...");
                }
            });
        } else {
            throw new NullPointerException("观察者不能为空！");
        }
        return this;
    }

    /**
     * 停止扫描
     */
    public BLEUtils stopScan(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mScanner.stopScan(new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    LogUtils.d(result);
                }

                @Override
                public void onBatchScanResults(List<ScanResult> results) {
                    super.onBatchScanResults(results);
                }

                @Override
                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);
                }
            });
        } else {
            mBluetoothAdapter.stopLeScan(new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {

                }
            });
        }
        OpenBleProgreessDialog.dismiss();
        if(!scanDisposable.isDisposed()){
            scanDisposable.dispose();
        }
        return this;
    }


}
